<template>
  <div class="my-project">
    <div class="project-main">
      <div class="project-manage">
        <div class="manage-title">
          <div class="my-project project-group">
            <span class="ml-0.5">我的分组</span>
            <Icon icon="ant-design:plus-outlined" @click="adding = true" />
          </div>
          <!-- 全部应用 -->
          <div
            class="my-project project-all"
            :class="{ 'project-checked-color': selectedGroupId === group.id }"
            @click="toggleProject(group.id)"
          >
            <span>{{ group.name }}</span>
            <span class="project-num">{{ group.children.length }}</span>
          </div>
          <div v-if="adding" class="new-group">
            <input v-focus class="edit-input" @blur="handleAddBlur" @keyup.enter="handleAddGroup" />
          </div>
        </div>
        <div class="manage-main" :class="{ draging: draging }">
          <!-- 未分组应用 -->
          <div
            class="main-project"
            :class="{ 'project-checked-color': selectedGroupId === unGroup.id }"
            @click="toggleProject(unGroup.id)"
            @dragover.prevent
            @dragenter="onDragEnter"
            @dragleave="onDragLeave"
            @drop="onDrop($event, unGroup)"
          >
            <span class="project-name project-ungrouped">{{ unGroup.name }}</span>
            <span class="project-num">{{ unGroup.children.length }}</span>
          </div>
          <!-- 其他分组 -->
          <div
            v-for="g of groups"
            :key="g.id"
            class="main-project group-project"
            :class="{ 'project-checked-color': selectedGroupId === g.id }"
            @click="toggleProject(g.id)"
            @dragover.prevent
            @dragenter="onDragEnter"
            @dragleave="onDragLeave"
            @drop="onDrop($event, g)"
          >
            <template v-if="g.editing">
              <input
                v-focus
                :default-value="g.name"
                class="edit-input"
                @blur="handleEditBlur($event, g)"
                @keyup.enter="handleEditGroup($event, g)"
              />
            </template>
            <template v-else>
              <span class="project-name">{{ g.name }}</span>
              <span class="project-num">{{ g.children.length }}</span>
              <span class="group-btns">
                <Icon class="mr-2" icon="ant-design:edit-outlined" @click="g.editing = true" />
                <Icon
                  class="btn-add-icon"
                  icon="ant-design:delete-outlined"
                  @click="handleDeleteGroup(g)"
                />
              </span>
            </template>
          </div>
        </div>
      </div>
      <div class="project-screen-list">
        <Spin :spinning="spinning">
          <ProjectList :group="selectedGroup" />
        </Spin>
      </div>
    </div>
  </div>
</template>
<script lang="tsx" setup>
  import { ref, computed, onMounted, provide } from 'vue';
  import { Modal, Spin } from 'ant-design-vue';
  import { Icon } from '/@/components/Icon';
  import { useProjectStore } from '/@/store/modules/datav/project';
  import { addClass, removeClass } from '/@/utils/domUtils';
  import { ProjectGroup } from '/@/utils/datav/project';

  import { projectInjectionKey } from './src/config';
  import ProjectList from './src/ProjectList.vue';

  const projectStore = useProjectStore();
  const group = computed(() => projectStore.group);
  const unGroup = computed(() => projectStore.unGroup);
  const groups = computed(() => projectStore.groups);
  const selectedGroup = computed(() => {
    if (selectedGroupId.value === -1) return group.value;
    if (selectedGroupId.value === 0) return unGroup.value;
    return groups.value.find((g) => g.id === selectedGroupId.value);
  });

  const { getProjects, createProjectGroup, deleteProjectGroup, moveProject } = projectStore;

  const adding = ref(false);
  const draging = ref(false);
  const spinning = ref(false);
  const selectedGroupId = ref(-1);

  /**
   * 失去焦点触发
   */
  const handleAddBlur = (e) => {
    if (!adding.value) return;
    const name = (e.target.value || '').trim();
    if (!name) {
      adding.value = false;
    }
  };
  /**
   * 添加回车
   */
  const handleAddGroup = async (e) => {
    if (!adding.value) return;
    const name = (e.target.value || '').trim();
    if (name) {
      try {
        adding.value = false;
        await createProjectGroup(name);
      } catch (error) {}
    } else {
      adding.value = false;
    }
  };
  /**
   * 编辑失去焦点
   * @param e
   * @param group
   */
  const handleEditBlur = (e: any, group: any) => {
    if (!group.editing) return;
    const newName = (e.target.value || '').trim();
    if (!newName || group.name === newName) {
      group.editing = false;
    }
  };
  /**
   * 编辑回车
   * @param e
   * @param group
   */
  const handleEditGroup = async (e: any, group: any) => {
    if (!group.editing) return;
    const newName = (e.target.value || '').trim();
    if (newName && group.name !== newName) {
      try {
        group.name = newName;
        group.editing = false;
      } catch (error) {}
    } else {
      group.editing = false;
    }
  };
  const handleDeleteGroup = (group: ProjectGroup) => {
    Modal.confirm({
      content: `${group.name} 删除后无法恢复，该分组中的可视化应用将全部移动到未分组，确认删除？`,
      centered: true,
      closable: true,
      okText: '确定',
      cancelText: '取消',
      onOk: async () => {
        await deleteProjectGroup(group.id);
        toggleProject(unGroup.value.id);
      },
    });
  };

  /**
   * 切换分类
   * @param id
   */
  const toggleProject = (id: number) => {
    selectedGroupId.value = id;
  };

  /**
   * 注入方法
   */
  provide(projectInjectionKey, {
    dragStart() {
      draging.value = true;
    },
    dragEnd() {
      draging.value = false;
    },
  });

  /**
   * 拖拽确定
   */
  const onDragEnter = (event: any) => {
    addClass(event.target, 'drag-enter');
  };

  /**
   * 拖拽层级
   */
  const onDragLeave = (event: any) => {
    removeClass(event.target, 'drag-enter');
  };

  /**
   * 放入
   */
  const onDrop = (event: any, toGroup: ProjectGroup) => {
    event.preventDefault();
    removeClass(event.target, 'drag-enter');
    const str = event.dataTransfer.getData('text');
    if (str) {
      const [pid, fromId] = str.split(',').map((m: string) => parseInt(m));
      if (fromId !== toGroup.id) {
        moveProject(pid, fromId, toGroup.id);
      }
    }
  };
  onMounted(() => {
    getProjects().finally(() => {
      // loading.value = false;
    });
  });
</script>
<style lang="less" scoped>
  .utils-ellipsis() {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .my-project {
    position: relative;
    user-select: none;

    .project-main {
      display: flex;
      flex: 1;
    }

    .project-manage {
      min-width: 240px;
      max-width: 240px;
      color: #fff;
      position: sticky;
      top: 70px;
      font-size: 14px;
      overflow-y: auto;
      height: calc(100vh - 150px);

      .manage-main {
        display: flex;
        flex-direction: column;
        font-size: 12px;

        &.draging {
          background: rgb(36 127 255 / 30%);
        }
      }

      .my-project {
        line-height: 36px;
        height: 36px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding-right: 30px;
      }

      .manage-title {
        .project-group {
          padding-left: 24px;
          height: 56px;
          border-bottom: 1px solid #27343e;
        }

        .btn-add-icon {
          font-size: 14px;
          cursor: pointer;

          &:hover {
            color: var(--datav-main-color);
          }
        }
      }

      .project-ungrouped {
        color: var(--datav-font-color);
      }

      .project-all {
        padding-left: 50px;
        transition: color 0.2s;
        cursor: pointer;

        &:hover {
          color: var(--datav-main-color);
        }
      }

      .project-checked-color {
        background-image: url('/@/assets/images/nav-menu-img.png');
        background-repeat: round;

        &:hover {
          color: #fff !important;
        }

        .project-name {
          color: #fff !important;
        }
      }

      .project-num {
        user-select: none;
        color: var(--datav-font-color);
      }

      .group-btns {
        display: none;
        color: var(--datav-main-color);

        i + i {
          margin-left: 10px;
        }
      }

      .main-project {
        position: relative;
        height: 36px;
        padding: 0 30px 0 50px;
        display: flex;
        font-size: 12px;
        align-items: center;
        justify-content: space-between;
        cursor: pointer;
        transition: color 0.2s;

        .project-name {
          width: 100px;
          font-size: 14px;
          text-overflow: ellipsis;
          overflow: hidden;
          white-space: nowrap;
          pointer-events: none;
        }

        &:hover {
          .project-name {
            color: var(--datav-main-color);
          }
        }

        &.drag-enter {
          background: var(--datav-body-bg);
        }
      }

      .group-project {
        &:hover {
          .project-num {
            display: none;
          }

          .group-btns {
            display: inline-block;
          }
        }
      }
    }

    .new-group {
      padding: 5px 30px 5px 50px;
    }

    .edit-input {
      .utils-ellipsis();

      background: var(--datav-bgcolor-2);
      color: #fff;
      padding: 0 10px;
      line-height: 30px;
      width: 100%;
      height: 30px;
      border: var(--datav-border-primary);
      transition: 0.2s;
      box-shadow: var(--datav-shadow);
    }

    .project-screen-list {
      padding-left: 20px;
      padding-right: 50px;
      width: 100%;
    }
  }
</style>
